package com.csun.cmny.provider.device.csun.gateway;

import com.csun.cmny.config.properties.CmnyProperties;
import com.csun.cmny.provider.device.csun.gateway.entity.CsunGatewayData;
import com.csun.cmny.provider.model.vo.device.DmcDeviceVo;
import com.csun.cmny.provider.service.DmcDeviceService;
import com.csun.cmny.provider.utils.DateUtil;
import com.csun.cmny.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-03-05 16:59
 * @Description:
 */
@Slf4j
@Configuration
public class GatewayInitRunner implements CommandLineRunner {

    @Resource
    private CmnyProperties cmnyProperties;

    @Resource
    private DmcDeviceService dmcDeviceService;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void run(String... args) throws Exception {

        List<DmcDeviceVo> dmcDeviceVoList = dmcDeviceService.queryGatewayList();
        for (DmcDeviceVo deviceVo : dmcDeviceVoList) {
            CsunGatewayData csunGatewayData = new CsunGatewayData();
            CsunGatewayVo2Data(deviceVo, csunGatewayData);

            redisTemplate.opsForValue().set(RedisKeyUtil.getCsunGatewayKey(csunGatewayData.getDeviceNo()),
                    csunGatewayData);
        }
        log.info("###GatewayInitRunner，finish<<<<<<<<<<<<<");
    }

    private void CsunGatewayVo2Data(DmcDeviceVo deviceVo, CsunGatewayData csunGatewayData) {
        csunGatewayData.setDeviceId(deviceVo.getId());
        csunGatewayData.setDeviceNo(deviceVo.getDeviceNo());
    }

    @Bean
    public MessageChannel gatewaySubChannel() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel gatewayPubChannel() {
        return new DirectChannel();
    }

    @Bean
    public MqttPahoClientFactory gatewayClientFactory() {
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setServerURIs(cmnyProperties.getMqtt().getGateway().getHost().split(","));
        mqttConnectOptions.setUserName(cmnyProperties.getMqtt().getGateway().getUsername());
        mqttConnectOptions.setPassword(cmnyProperties.getMqtt().getGateway().getPassword().toCharArray());
        mqttConnectOptions.setKeepAliveInterval(60);
        mqttConnectOptions.setConnectionTimeout(30);
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(mqttConnectOptions);

        return factory;
    }

    @Bean
    public MessageProducer gatewayMessageProducer() {

        String[] topics = cmnyProperties.getMqtt().getGateway().getTopic().split(",");

        MqttPahoMessageDrivenChannelAdapter adapter =
                new MqttPahoMessageDrivenChannelAdapter(cmnyProperties.getMqtt().getGateway().getHost(),
                        cmnyProperties.getMqtt().getGateway().getSubClientId()
                                + DateUtil.dateToStrs(new Date()),
                        gatewayClientFactory(), topics);

        adapter.setCompletionTimeout(30000);
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(1);
        adapter.setOutputChannel(gatewaySubChannel());

        return adapter;
    }

    @Bean
    @ServiceActivator(inputChannel = "gatewayPubChannel")
    public MessageHandler gatewayPubMessageHandler() {
        MqttPahoMessageHandler messageHandler =
                new MqttPahoMessageHandler(cmnyProperties.getMqtt().getGateway().getPubClientId()
                        + DateUtil.dateToStrs(new Date()), gatewayClientFactory());
        messageHandler.setAsync(true);
        messageHandler.setDefaultTopic("God");
        return messageHandler;
    }

    @Bean
    @ServiceActivator(inputChannel = "gatewaySubChannel")
    public MessageHandler GatewayMessageHandler() {
        return new GatewayMessageHandler();
    }
}
